package biz.datalk.industrialland.common.validated.validator;

import biz.datalk.industrialland.common.validated.DateFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @author tarofang@163.com
 * @date 2019-08-19
 */
@Slf4j
public class DateFormatValidator implements ConstraintValidator<DateFormat, String> {
    private String fmt;
    private String message;
    private String blankMessage;
    private boolean required;


    @Override
    public void initialize(DateFormat constraintAnnotation) {
        fmt = constraintAnnotation.fmt();
        message = constraintAnnotation.message();
        blankMessage = constraintAnnotation.blankMessage();
        required = constraintAnnotation.required();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return this.required ? requireTrue(value, context) : requireFalse(value, context);
    }

    private boolean requireTrue(String value, ConstraintValidatorContext context) {
        if (StringUtils.isBlank(value)) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(blankMessage).addConstraintViolation();
            return Boolean.FALSE;
        }

        return checkDateFmt(value, context);
    }

    private boolean requireFalse(String value, ConstraintValidatorContext context) {
        if (StringUtils.isBlank(value)) {
            return Boolean.TRUE;
        }
        return checkDateFmt(value, context);
    }

    private boolean checkDateFmt(String value, ConstraintValidatorContext context) {
        try {
            DateUtils.parseDate(value, fmt);
            return Boolean.TRUE;
        } catch (Exception ex) {
            log.warn("Invalid date. [value={}, format={}]", value, fmt);
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
            return Boolean.FALSE;
        }
    }

}
